package com.cx.bank.handler;

import com.cx.bank.dao.BankDaoImpl;
import com.cx.bank.dao.BankDaoInterface;
import com.cx.bank.manager.IManager;
import com.cx.bank.manager.ManagerImpl;
import com.cx.bank.pojo.Log;
import com.cx.bank.pojo.User;
import com.cx.bank.util.AccountOverDrawnException;
import com.cx.bank.util.DBHelper;
import com.cx.bank.util.LogUtil;

import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.SimpleFormatter;

/**
 * @author jxau_scf
 * @date 2021/7/25 - 19:22
 */
public class MyInVocationHandler implements InvocationHandler {
    private String userName;
    private Object target;

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(this.target, args);
//        LoggingBankOperation(args[0].toString(),method.getName(),new Date());

        //配置日志信息
        Log log = new Log();
        Integer userId = LogUtil.findUserIdByUserName(userName);
        log.setUserId(userId);
        String methodName = method.getName();
        log.setLogType(methodName);
        if (methodName.equals("withdrawals") || methodName.equals("deposit")){
            log.setLogAmount((Double) args[1]);
        }else if (methodName.equals("transfer")){
            log.setLogAmount((Double) args[2]);
        }else if (methodName.equals("register")){
            log.setLogAmount(((User)args[0]).getBalance());
        } else {
            log.setLogAmount(0.0);
        }
        //数据库插入日志
        LoggingBankOperationOnDataBase(log);
        return result;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    private void LoggingBankOperation(String user, String methodName, Date date) throws IOException {
        File logfile = new File("E:\\Worksapces\\idea2019.3.1\\bank1.9\\userLog.txt");
            FileOutputStream fos = new FileOutputStream(logfile, true);
            OutputStreamWriter opw = new OutputStreamWriter(fos, "utf-8");
            opw.append("用户"+user+"|在"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)+"|执行了"+methodName+"操作"+'\n');
            opw.close();
            fos.close();
    }

    private void LoggingBankOperationOnDataBase(Log log){
        Connection conn = DBHelper.getConn();
        String sql = "insert into t_log(log_type,log_amount,user_id) values(?,?,?)";
        List<Object> logList = new ArrayList<>();
        logList.add(log.getLogType());
        logList.add(log.getLogAmount());
        logList.add(log.getUserId());
        boolean insertLogStatus = DBHelper.updateDate(conn, sql, logList);
        if (insertLogStatus) {
            System.out.println(log.getUserId()+"号用户，日志添加成功！");
            System.out.println(log);
        }
    }


    public static void main(String[] args) throws AccountOverDrawnException, SQLException {
//        BankDaoInterface bankDao = new BankDaoImpl();
//        MyInVocationHandler handler = new MyInVocationHandler();
//        handler.setTarget(bankDao);
//        BankDaoInterface proxy = (BankDaoInterface)handler.getProxy();
//        boolean depositStatus = proxy.updateMoney("aaa", 100);
//        System.out.println(depositStatus);

        IManager manager = ManagerImpl.getInstance();
        MyInVocationHandler handler = new MyInVocationHandler();
        handler.setTarget(manager);
        handler.setUserName("aaa");
        IManager proxy = (IManager)handler.getProxy();
        System.out.println(proxy.inquiry("aaa"));
//        boolean depositStatus = proxy.deposit("aaa", 20);
//        System.out.println(depositStatus);


    }
}
